home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / dev / gcc / fd2inline.lha / fd2inline.c < prev    next >
C/C++ Source or Header  |  1995-06-06  |  29KB  |  1,230 lines

  1. /*
  2.  * fd2inline
  3.  *
  4.  * should be able to parse CBM fd files and generate vanilla inline calls
  5.  * for gcc. Works as a filter. This is a 0.9 evaluation version. Don't expect
  6.  * miracles (yet...).
  7.  *
  8.  * by Wolfgang Baron, all rights reserved.
  9.  *
  10.  * improved, updated, simply made workable by Rainer F. Trunz
  11.  *
  12.  */
  13.  
  14. /* $Id$ */
  15.  
  16. #include <stddef.h>
  17. #include <stdlib.h>
  18. #include <stdio.h>
  19. #include <string.h>
  20. #include <ctype.h>
  21.  
  22. /*
  23.  * The program has a few sort of class definitions, which are the result of
  24.  * object oriented thinking, to be imlemented in plain C. I just haven't
  25.  * had the time to learn C++ or install the compiler. The design does however
  26.  * improve robustness, which allows the source to be used over and over again.
  27.  * if you use this code, please leave a little origin note.
  28.  *
  29.  */
  30.  
  31. const char *version_str= "$VER$ $Revision$ $Date$";
  32.  
  33. /*
  34.  * These are general definitions including types for defining registers etc.
  35.  */
  36.  
  37. #ifdef DEBUG
  38.  
  39. #define DBP(a) printf2(a)
  40.  
  41. static __inline void printf2( const char *fmt, ... )
  42. {
  43.   fprintf (stderr, fmt, (char *)(&fmt+1) );
  44. }
  45.  
  46. #else
  47.  
  48. #define DBP(a)
  49.  
  50. #endif
  51.  
  52.  
  53. #define REGS 16  /* d0=0,...,a7=15 */
  54.  
  55. typedef enum {
  56.   d0, d1, d2, d3, d4, d5, d6, d7, a0, a1, a2, a3, a4, a5, a6, a7, illegal
  57. } regs;
  58.  
  59. typedef unsigned char uchar, shortcard;
  60. typedef unsigned long ulong;
  61.  
  62. typedef enum { false, nodef, real_error } Error;
  63.  
  64. static char *IHead =
  65.     "#ifndef _INLINE_%s_H\n"
  66.     "#define _INLINE_%s_H\n\n"
  67.     "#ifndef _CDEFS_H_\n"
  68.     "#include <sys/cdefs.h>\n"
  69.     "#endif\n"
  70.     "#ifndef _INLINE_STUBS_H_\n"
  71.     "#include <inline/stubs.h>\n"
  72.     "#endif\n\n"
  73.     "__BEGIN_DECLS\n\n"
  74.     "#ifndef BASE_EXT_DECL\n"
  75.     "#define BASE_EXT_DECL\n"
  76.     "#define BASE_EXT_DECL0 extern struct Library *%sBase;\n"
  77.     "#endif\n"
  78.     "#ifndef BASE_PAR_DECL\n"
  79.     "#define BASE_PAR_DECL\n"
  80.     "#define BASE_PAR_DECL0 void\n"
  81.     "#endif\n"
  82.     "#ifndef BASE_NAME\n"
  83.     "#define BASE_NAME %sBase\n"
  84.     "#endif\n\n"
  85.     "BASE_EXT_DECL0\n\n";
  86.  
  87. static char *IFoot =
  88.     "#undef BASE_EXT_DECL\n"
  89.     "#undef BASE_EXT_DECL0\n"
  90.     "#undef BASE_PAR_DECL\n"
  91.     "#undef BASE_PAR_DECL0\n"
  92.     "#undef BASE_NAME\n\n"
  93.     "__END_DECLS\n\n"
  94.     "#endif /* _INLINE_%s_H */\n";
  95.  
  96. char BaseName[32];
  97. char BaseNamU[32];
  98.  
  99. /*
  100.  * just some support functions, no checking
  101.  */
  102.  
  103. char *NewString( char **new, const char * old )
  104. {
  105.     const char *high;
  106.     ulong len;
  107.  
  108.   while ( *old && (' ' == *old || '\t' == *old) ) old++;
  109.   len= strlen( old );
  110.   for (high=old+len-1; high>=old && (' ' == *high || '\t' == *high); high-- );
  111.   high++;
  112.   len= high-old;
  113.   *new = (char *)malloc( 1+len );
  114.   if (*new) {
  115.     strncpy( *new, old, len );
  116.     (*new)[len]= '\0'; }
  117.   else {
  118.     fprintf (stderr, "no mem for string\n" ); }
  119.   return *new;
  120. }
  121.  
  122. static __inline void illparams (const char *funcname)
  123. {
  124.   fprintf (stderr, "%s: illegal Parameters\n", funcname );
  125. }
  126.  
  127. static __inline const char * RegStr( regs reg )
  128. {
  129.     const char *myregs[]= {
  130.       "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
  131.       "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "illegal" };
  132.  
  133.   if ( reg > illegal ) reg= illegal;
  134.   if ( reg < d0 )      reg= d0;
  135.   return myregs[reg];
  136. }
  137.  
  138. /*
  139.  *    StrNRBrk
  140.  *
  141.  * searches string in from position at downwards, as long as in does not
  142.  * contain any character in not.
  143.  *
  144.  */
  145.  
  146. const char * StrNRBrk( const char * in, const char *not, const char * at )
  147. {
  148.     const char *chcheck;
  149.     Error ready;
  150.  
  151.   chcheck = "";   /* if at<in, the result will be NULL */
  152.   for (ready=false; ready==false && at>=in; ) {
  153.     for (chcheck=not; *chcheck && *chcheck != *at; chcheck++);
  154.     if (*chcheck) ready= real_error;
  155.     else at--;
  156.   }
  157.   DBP(( "{%c}", *chcheck ));
  158.   return *chcheck ? at : NULL;
  159. }
  160.  
  161. /*
  162.  *    binSearch
  163.  *
  164.  * A binary search routine, wich operates on an array like you would use
  165.  * for qsort. The prototype does not contain the (*) bug...
  166.  *
  167.  * returns the address of the (a?) fitting object, or NULL;
  168.  *
  169.  * the binary intersection is (low+high)/2, so the highest value will never
  170.  * be reached, but the lowest value will. In the while condition, the diff
  171.  * has to be called last in case we got an empty array.
  172.  *
  173.  */
  174.  
  175. void *binSearch (void ** array, size_t elements, const void *lookfor,
  176.          int cmpfunc(const void **, const void **))
  177. {
  178.     size_t low, high, index;
  179.     int    diff;
  180.  
  181.   DBP(( "bs(%ld): ", (long)elements ));
  182.  
  183.   diff = 1;    /* this needs to be so in case we got an empty array... */
  184.  
  185.   low=0, high= elements;  /* our algorithm never reaches elements */
  186.  
  187.   while( index= (high+low)/2,  /* somewhere inbetween */
  188.      high!=low && (diff= cmpfunc((const void **)array+index,&lookfor)) ) {
  189.     if (0<diff) {
  190.       high= index;  /* our value was too big, so grow downwards */
  191.       DBP(( "<" )); }
  192.     else {
  193.       low= index + 1;       /* the low value will be reached */
  194.       DBP(( ">" )); }
  195.     DBP(( "%ld ", (long)index ));
  196.   }
  197.   DBP(( "->%ld\n", diff ? -1L : (long)index ));
  198.   return diff ? NULL : array[index];  /* bingo */
  199. }
  200.  
  201. /*
  202.  *    CLASS fdFile
  203.  *
  204.  * stores a file with a temporary buffer (static length, sorry), a line number,
  205.  * an offset (used for library offsets and an error field.
  206.  * When there's no error, line will contain line #lineno and offset will be
  207.  * the last offset set by the interpretation of the last line. If there's been
  208.  * no ##bias line, this field assumes a bias of 30, which is the standard bias.
  209.  * It is assumed offsets are always negative.
  210.  */
  211.  
  212. #define fF_BUFSIZE 1024
  213. #define fF_BUFFMT  "%1024[~ß]"
  214.  
  215. /* all you need to know about an fdFile you parse */
  216.  
  217. typedef struct {
  218.     FILE * file;        /* the file we're reading from  */
  219.     char   line[ fF_BUFSIZE ];    /* the current line        */
  220.     ulong  lineno;        /* current line number        */
  221.     long   offset;        /* current fd offset (-bias)    */
  222.     Error  error;        /* is everything o.k.        */
  223. } fdFile;
  224.  
  225.  
  226. fdFile *fF_ctor(const char *fname);
  227. static __inline
  228. void         fF_dtor(             fdFile *obj );
  229. static __inline
  230. void         fF_SetError(         fdFile *obj, Error error );
  231. static __inline 
  232. void         fF_SetOffset(        fdFile *obj, long at );
  233. Error         fF_readln(           fdFile *obj );
  234. static __inline
  235. Error         fF_GetError(   const fdFile *obj );
  236. static __inline
  237. long         fF_GetOffset(  const fdFile *obj );
  238. char       * fF_FuncName(         fdFile *obj );       /* return name or null */
  239.  
  240.  
  241. fdFile * fF_ctor( const char *fname )
  242. {
  243.   fdFile * result;
  244.  
  245.   if (fname) {
  246.     result= (fdFile *) malloc( sizeof(fdFile) );
  247.     if (result) {
  248.       result->file= fopen( fname, "r" );
  249.       if (result->file) {
  250.     result->lineno= 0;
  251.     fF_SetOffset( result, -30);
  252.     fF_SetError( result, false );
  253.     result->line[0]= '\0';
  254.       }
  255.     } }
  256.   else {
  257.     result= NULL;
  258.     illparams( "fF_ctor" ); }
  259.   return result;
  260. }
  261.  
  262.  
  263. static __inline
  264. void fF_dtor( fdFile *obj )
  265. {
  266.   fclose( obj->file );
  267.   free( obj );
  268. }
  269.  
  270.  
  271. static __inline void fF_SetError( fdFile *obj, Error error )
  272. {
  273.   if (obj)
  274.     obj->error= error;
  275.   else
  276.     illparams( "fF_SetError" );
  277. }
  278.  
  279.  
  280. static __inline void fF_SetOffset( fdFile *obj, long at )
  281. {
  282.   if (obj)
  283.     obj->offset= at;
  284.   else
  285.     illparams( "fFSetOffset" );
  286. }
  287.  
  288.  
  289. Error fF_readln( fdFile *obj )
  290. {
  291.   char *low, *bpoint;
  292.   long glen, /* the length we read until now */
  293.   len;       /* the length of the last segment */
  294.  
  295.   if (obj) {
  296.     low= obj->line;
  297.     glen= 0;
  298.     do {
  299.       obj->lineno++;
  300.       if (!fgets( low, fF_BUFSIZE-1-glen, obj->file )) {
  301.     fF_SetError( obj, real_error );
  302.     obj->line[0]= '\0';
  303.     return real_error; }
  304.       if (low==strpbrk(low,"*#/")) {
  305.     DBP(( "in# %s\n", obj->line ));
  306.     return false; }
  307.       len= strlen( low );
  308.       bpoint= low+len-1;
  309.       if ('\n'==*bpoint) *bpoint='\0', bpoint--, len--;
  310.       if (';'==*bpoint || ')'==*bpoint ) {
  311.     DBP(( "\nin: %s\n", obj->line ));
  312.     return false; }
  313.       glen+= len;
  314.       low+= len;
  315.       if (glen >= fF_BUFSIZE-10) {      /* somewhat pessimistic ? */
  316.     fF_SetError(obj, real_error);
  317.     fprintf (stderr, "line %lu too long.\n", obj->lineno );
  318.     return real_error;
  319.       }
  320.       DBP(( "+" ));
  321.     } while (!0);
  322.   }
  323.   illparams( "fF_readln" );
  324.   return real_error;
  325. }
  326.  
  327. /*
  328.  *    fF_FuncName
  329.  *
  330.  * checks if it can find a function-name and return it's address, or NULL
  331.  * if the current line does not seam to contain one. The return value will
  332.  * be a pointer into a malloced buffer, thus the caller will have to free().
  333.  */
  334.  
  335. char * fF_FuncName (fdFile *obj)
  336. {
  337.   const char *lower;
  338.   const char *upper;
  339.   char *buf;
  340.   long obraces;        /* count of open braces */
  341.   Error ready;        /* ready with searching */
  342.  
  343.   if (!obj || real_error==fF_GetError(obj)) {
  344.     illparams( "fF_FuncName" );
  345.     return NULL;
  346.   }
  347.   if (obj->line==strpbrk(obj->line, "#*/")) {
  348.     fF_SetError( obj, nodef );
  349.     return NULL;
  350.   }
  351.  
  352.   lower= NULL;
  353.   buf= NULL;
  354.  
  355.   if (obj && false == fF_GetError(obj)) {
  356.     if ( upper=strrchr(obj->line, ')' )) {
  357.       DBP(( "end:%s:", upper ));
  358.       for(obraces= 1, ready= false; false== ready; upper=lower ) {
  359.     lower= StrNRBrk( obj->line, "()", --upper );
  360.     if (lower) {
  361.       switch (*lower) {
  362.         case ')': {
  363.           obraces++;
  364.           DBP(( " )%ld%s", obraces, lower ));
  365.           break; }
  366.         case '(': {
  367.           obraces--;
  368.           DBP(( " (%ld%s", obraces, lower ));
  369.           if (!obraces) ready= nodef;
  370.           break; }
  371.         default: {
  372.           fprintf (stderr, "faulty StrNRBrk\n" );
  373.         }
  374.       } }
  375.     else {
  376.       fprintf (stderr, "'(' or ')' expected in line %lu.\n", obj->lineno );
  377.       ready= real_error;
  378.     }
  379.       }
  380.       if (nodef==ready) {   /* we found the matching '(' */
  381.       long newlen;
  382.     upper--;
  383.  
  384.     while (upper>=obj->line && (' ' == *upper || '\t' == *upper) ) upper--;
  385.  
  386.     lower= StrNRBrk( obj->line, " \t*)", upper );
  387.  
  388.     if (!lower) lower=obj->line;
  389.     else lower++;
  390.  
  391.     newlen= upper-lower+2;
  392.     buf= malloc( newlen );
  393.  
  394.     if (buf) {
  395.       strncpy( buf, lower, --newlen );
  396.       buf[newlen]= '\0';
  397.     }
  398.     else fprintf (stderr, "no mem for fF_FuncName" );
  399.       }
  400.     }
  401.   }
  402.   else illparams( "fF_FuncName" );
  403.   return buf;
  404. }
  405.  
  406.  
  407.  
  408. static __inline Error fF_GetError( const fdFile *obj )
  409. {
  410.   if (obj) return obj->error;
  411.   illparams( "fF_GetError" );
  412.   return real_error;
  413. }
  414.  
  415.  
  416.  
  417. static __inline long fF_GetOffset( const fdFile *obj )
  418. {
  419.   if (obj) return obj->offset;
  420.   illparams( "fF_GetOffset" );
  421.   return -1;
  422. }
  423.  
  424. /* ####################################################################### */
  425. /* ####################################################################### */
  426. /* ####################################################################### */
  427.  
  428. /*
  429.  *    CLASS fdDef
  430.  */
  431.  
  432. typedef struct {
  433.   char * name;
  434.   char * type;
  435.   long     offset;
  436.   regs     reg[REGS];
  437.   char * param[REGS];
  438.   char * proto[REGS];
  439. } fdDef;
  440.  
  441. fdDef       * fD_ctor(      void );
  442. void         fD_dtor(            fdDef *obj );
  443. static __inline
  444. void         fD_NewName(         fdDef *obj, const char *newname );
  445. void         fD_NewParam(        fdDef *obj, shortcard at, const char * newstr );
  446. void         fD_NewProto(        fdDef *obj, shortcard at, const char * newstr );
  447. static __inline
  448. void         fD_NewReg(          fdDef *obj, shortcard at, regs reg );
  449. static __inline
  450. void         fD_NewType(         fdDef *obj, const char * newstr );
  451. static __inline
  452. void         fD_SetOffset(       fdDef *obj, long off );
  453. Error         fD_parsefd(         fdDef *obj, fdFile * infile );
  454. Error         fD_parsepr(         fdDef *obj, fdFile * infile );
  455. static __inline
  456. const char * fD_GetName(   const fdDef *obj );
  457. static __inline
  458. long         fD_GetOffset( const fdDef *obj );
  459. static __inline
  460. const char * fD_GetParam(  const fdDef *obj, shortcard at );
  461. static __inline
  462. regs         fD_GetReg(    const fdDef *obj, shortcard at );
  463. static __inline
  464. const char * fD_GetRegStr( const fdDef *obj, shortcard at );
  465. static __inline
  466. const char * fD_GetType(   const fdDef *obj );
  467. static __inline
  468. shortcard    fD_ParamNum(  const fdDef *obj );
  469. static __inline
  470. shortcard    fD_ProtoNum(  const fdDef *obj );
  471. static __inline
  472. shortcard    fD_RegNum(    const fdDef *obj );
  473. int         fD_cmpName(   const fdDef **big, const fdDef **small );
  474. void         fD_write(     const fdDef *obj );
  475.  
  476. char * fD_nostring = "";
  477.  
  478.  
  479. fdDef * fD_ctor( void )
  480. {
  481.   fdDef * result;
  482.   regs    count;
  483.  
  484.   result= (fdDef *) malloc(sizeof(fdDef));
  485.   if (result) {
  486.     result->name= fD_nostring;
  487.     result->type= fD_nostring;
  488.     for ( count=d0; count<illegal; count++ ) {
  489.       result->reg[count]= illegal;
  490.       result->param[count]= fD_nostring;   /* if (!strlen) dont't free() */
  491.       result->proto[count]= fD_nostring;
  492.     } }
  493.   return result;
  494. }
  495.  
  496. /* free all resources and make the object as illegal as possible */
  497.  
  498. void fD_dtor( fdDef * obj )
  499. {
  500.   regs count;
  501.  
  502.   if (obj) {
  503.     if (!obj->name) fprintf (stderr, "fD_dtor: null name" );
  504.     else if (obj->name != fD_nostring) free( obj->name );
  505.     if (!obj->type) fprintf (stderr, "fD_dtor: null type" );
  506.     else if (obj->type != fD_nostring) free( obj->type );
  507.     obj->name= obj->type= NULL;
  508.  
  509.     for (count= d0; count<illegal; count++) {
  510.       obj->reg[count]= illegal;
  511.       if (!obj->param[count]) fprintf (stderr, "fD_dtor: null param" );
  512.       else if (obj->param[count] != fD_nostring) free(obj->param[count]);
  513.       if (!obj->proto[count]) fprintf (stderr, "fD_dtor: null proto" );
  514.       else if (obj->proto[count] != fD_nostring) free(obj->proto[count]);
  515.       obj->param[count]= obj->proto[count]= NULL; }
  516.     free(obj);
  517.   }
  518.   else fprintf (stderr, "dfDef_dtor(NULL)\n" );
  519. }
  520.  
  521.  
  522.  
  523. static __inline
  524. void fD_NewName (fdDef *obj, const char *newname)
  525. {
  526.   if (obj && newname) {
  527.     if (obj->name && fD_nostring != obj->name ) free( obj->name );
  528.     if (!NewString( &obj->name, newname )) obj->name= fD_nostring;
  529.   }
  530.   else illparams( "fD_NewName" );
  531. }
  532.  
  533.  
  534. void fD_NewParam (fdDef *obj, shortcard at, const char * newstr)
  535. {
  536.   char *pa;
  537.  
  538.   if (newstr && obj && at>=d0 && at<illegal) {
  539.     pa = obj->param[at];
  540.  
  541.     if (pa && fD_nostring != pa) free(pa);
  542.  
  543.     while (*newstr == ' ' || *newstr == '\t')
  544.         newstr++;
  545.  
  546.     if (NewString (&pa, newstr))
  547.       obj->param[at]= pa;
  548.     else
  549.       obj->param[at]= fD_nostring;
  550.   }
  551.   else illparams( "fD_NewParam" );
  552. }
  553.  
  554.  
  555. static __inline
  556. void RealProto (char *wrgp)
  557. {
  558.  char *t;
  559.  t = wrgp + strlen(wrgp)-1;
  560.  
  561.  while (*t != ' ' && *t != '\t' && *t != '*') t--;
  562.  
  563.  if (*t == '*')
  564.    *++t = '\0';
  565.  else
  566.    *t = '\0';
  567. }
  568.  
  569. void fD_NewProto (fdDef *obj, shortcard at, const char *newstr)
  570. {
  571.   char *pr;
  572.  
  573.   if (newstr && obj && at>=d0 && at<illegal) {
  574.     pr = obj->proto[at];
  575.  
  576.     if (pr && fD_nostring != pr) free(pr);
  577.  
  578.     RealProto (newstr);
  579.  
  580.     if (NewString (&pr, newstr))
  581.       obj->proto[at]= pr;
  582.     else
  583.       obj->proto[at]= fD_nostring;
  584.   }
  585.   else illparams( "fD_NewProto" );
  586. }
  587.  
  588.  
  589. static __inline
  590. void fD_NewReg( fdDef *obj, shortcard at, regs reg )
  591. {
  592.   if (obj && at>=d0 && at<illegal && reg>=d0 && reg<=illegal)
  593.     obj->reg[at] = reg;
  594.   else illparams( "fD_NewReg" );
  595. }
  596.  
  597.  
  598. static __inline
  599. void fD_NewType( fdDef *obj, const char *newtype )
  600. {
  601.   if (obj && newtype) {
  602.     if (obj->type && fD_nostring != obj->type ) free( obj->type );
  603.     if (!NewString( &obj->type, newtype )) obj->type= fD_nostring; }
  604.   else illparams( "fD_NewType" );
  605. }
  606.  
  607.  
  608. static __inline
  609. void fD_SetOffset( fdDef *obj, long off )
  610. {
  611.   if (obj)
  612.     obj->offset=off;
  613.   else
  614.     illparams( "fD_SetOffset" );
  615. }
  616.  
  617. /*    fD_parsefd
  618.  *
  619.  *  parse the current line. Needs to copy input, in order to insert \0's
  620.  *  RETURN
  621.  *    fF_GetError(infile):
  622.  *    false = read a definition.
  623.  *    nodef = not a definition on line (so try again)
  624.  *    error = real error
  625.  */
  626.  
  627. Error fD_parsefd( fdDef * obj, fdFile * infile )
  628. {
  629.   enum  parse_info { name, params, regs, ready } parsing;
  630.   char  *buf, *bpoint, *bnext;
  631.   ulong index;
  632.  
  633.   if (obj && infile && (false == fF_GetError(infile))) {
  634.     parsing= name;
  635.  
  636.     if (!NewString( &buf, infile->line )) {
  637.       fprintf (stderr, "no mem for line %lu\n", infile->lineno );
  638.       fF_SetError( infile, real_error );
  639.     }
  640.     bpoint = buf;  /* so -Wall keeps quiet */
  641.  
  642.     /* printf("copied %lu: %s", infile->lineno, buf ); */
  643.  
  644.     /* try to parse the line until there's an error or we are done */
  645.  
  646.     while (ready != parsing && false == fF_GetError(infile)) {
  647.  
  648.       switch (parsing) {
  649.  
  650.     case name: {
  651.  
  652.       switch (buf[0]) {
  653.  
  654.         case '#': {
  655.  
  656.           if (strncmp("##base", buf, 6) == 0) {
  657.         bnext = buf + 6;
  658.         while (*bnext == ' ' || *bnext == '\t')
  659.           bnext++;
  660.         strncpy (BaseName, bnext, strstr (bnext, "Base")-bnext);
  661.           } else
  662.           if (strncmp("##bias", buf, 6) == 0) {
  663.         if (!sscanf(buf+6, "%ld", &infile->offset)) {
  664.           fprintf (stderr, "illegal ##bias in line %lu: %s\n",
  665.                infile->lineno, infile->line );
  666.           fF_SetError( infile, real_error );
  667.           break;    /* avoid nodef */
  668.         }
  669.         else {
  670.           if (fF_GetOffset(infile) > 0)
  671.             fF_SetOffset(infile, -fF_GetOffset(infile));
  672.  
  673.           /* printf("set offset to %ld\n", fFGetOffset(infile); */
  674.         }
  675.           }        /* drop through for error comment */
  676.         }
  677.         case '*':
  678.  
  679.           fF_SetError( infile, nodef ); /* try again somewhere else */
  680.           break;
  681.  
  682.         default: {        /* assume a regular line here */
  683.  
  684.           parsing = name;    /* switch (parsing) */
  685.  
  686.           for (index=0; buf[index] && buf[index]!='('; index++);
  687.  
  688.           if (!buf[index]) {    /* oops, no fd ? */
  689.         fprintf (stderr, "not an fd, line %lu: %s\n",
  690.              infile->lineno, buf /* infile->line */ );
  691.         fF_SetError(infile, nodef); } /* maybe next time */
  692.           else {
  693.         buf[index]=0;
  694.  
  695.         fD_NewName (obj, buf);
  696.         fD_SetOffset (obj, fF_GetOffset(infile));
  697.  
  698.         bpoint  = buf+index+1;
  699.         parsing = params;    /* continue the loop */
  700.           }
  701.         } }
  702.       break; }
  703.  
  704.     case params: {
  705.  
  706.       char *bptmp;    /* needed for fD_NewParam */
  707.  
  708.       /* look for parameters now */
  709.  
  710.       for ( bnext = bpoint;
  711.         *bnext && *bnext!=',' && *bnext!=')';
  712.         bnext++ );
  713.  
  714.       if (*bnext) {
  715.         bptmp=bpoint;
  716.  
  717.         if (*bnext == ')') {
  718.           if (bnext[1] != '(') {
  719.         fprintf (stderr, "registers expected in line %lu: %s\n",
  720.              infile->lineno, infile->line );
  721.         fF_SetError(infile, nodef); }
  722.           else {
  723.         parsing = regs;
  724.         bpoint  = bnext+2;
  725.           }
  726.         }
  727.         else bpoint = bnext+1;
  728.  
  729.         /* terminate string and advance to next item */
  730.  
  731.         *bnext= '\0';
  732.         fD_NewParam (obj, fD_ParamNum(obj), bptmp);
  733.       }
  734.       else {
  735.         fF_SetError(infile, nodef);
  736.         fprintf (stderr, "param expected in line %lu: %s\n",
  737.              infile->lineno, infile->line );
  738.       }
  739.       break; } /* switch parsing */
  740.  
  741.     case regs: {        /* look for parameters now */
  742.  
  743.       for ( bnext= bpoint
  744.           ; *bnext && *bnext!='/' && *bnext!=',' && *bnext!=')'
  745.           ; bnext++ );
  746.  
  747.       if (*bnext) {
  748.         if (')'==*bnext) {    /* wow, we've finished */
  749.           fF_SetOffset( infile, fF_GetOffset(infile)-6 );
  750.           parsing= ready;
  751.         }
  752.         *bnext= '\0';
  753.  
  754.         bpoint[0] = tolower (bpoint[0]);
  755.  
  756.         if (('d'==bpoint[0] || 'a'==bpoint[0])
  757.         && '0'<=bpoint[1] && '8'>=bpoint[1] && bnext == bpoint+2)
  758.           fD_NewReg( obj, fD_RegNum(obj),
  759.              bpoint[1]-'0'+(bpoint[0]=='a'?8:0) );
  760.         else if (bnext!=bpoint) { /* it is when our function is void */
  761.           fprintf (stderr, "illegal register %s in line %ld\n",
  762.                bpoint, infile->lineno );
  763.           fF_SetError(infile, nodef); }
  764.         bpoint= bnext+1;
  765.       }
  766.       else {
  767.         fF_SetError(infile, nodef);
  768.         fprintf (stderr, "reg expected in line %lu\n", infile->lineno );
  769.       }
  770.       break; }  /* switch parsing */
  771.  
  772.     case ready: {
  773.       fprintf (stderr, "internal error, use another compiler.\n" );
  774.       break;
  775.     }
  776.       } }
  777.     free( buf );
  778.     return fF_GetError(infile); }
  779.   else {
  780.     illparams( "fD_parsefd" );
  781.     return real_error;
  782.   }
  783. }
  784.  
  785. Error fD_parsepr (fdDef *obj, fdFile * infile)
  786. {
  787.   char    *buf;       /* a copy of infile->line             */
  788.   char    *bpoint,   /* cursor in buf                 */
  789.     *bnext,    /* looking for the end             */
  790.     *lowarg;   /* beginning of this argument         */
  791.   long    obraces;   /* count of open braces             */
  792.   regs    count,     /* count parameter number             */
  793.     args;       /* the number of arguments for this function  */
  794.  
  795.   if (!(obj && infile && false==fF_GetError(infile))) {
  796.     illparams ("fD_parsepr");
  797.     fF_SetError (infile, real_error);
  798.     return real_error;
  799.   }
  800.   if (!NewString (&buf, infile->line)) {
  801.     fprintf (stderr, "no mem for fD_parsepr\n");
  802.     fF_SetError (infile, real_error);
  803.     return real_error;
  804.   }
  805.   fF_SetError (infile, false);
  806.  
  807.   if (bpoint = strstr (buf, fD_GetName(obj))) {
  808.  
  809.     while (--bpoint>=buf && (' '== *bpoint || '\t'== *bpoint));
  810.     *++bpoint= '\0';
  811.  
  812.     fD_NewType (obj, buf);
  813.  
  814.     while (bpoint && '('!=*bpoint++);        /* one beyond '(' */
  815.  
  816.     lowarg  = bpoint;
  817.     obraces = 0;
  818.  
  819.     for (count=0, args=fD_RegNum(obj); count<args; bpoint= bnext+1) {
  820.  
  821.       while (*bpoint && (*bpoint==' ' || *bpoint=='\t')) /* ignore spaces */
  822.     bpoint++;    
  823.  
  824.       bnext= strpbrk(bpoint, "(),");
  825.  
  826.       if (bnext) {
  827.     switch (*bnext) {
  828.  
  829.       case '(': {
  830.  
  831.         obraces++;
  832.         DBP(( "< (%ld%s >", obraces, bnext ));
  833.         break; }
  834.  
  835.       case ')': {
  836.  
  837.         if (obraces) {
  838.           DBP(( "< )%ld%s >", obraces, bnext ));
  839.           obraces--; }
  840.         else {
  841.           *bnext= '\0';
  842.           DBP(( "< )0> [LAST PROTO=%s]", lowarg ));
  843.           fD_NewProto( obj, count, lowarg );
  844.           lowarg= bnext+1;
  845.  
  846.           if (count!=args-1) {
  847.         /*
  848.             fprintf (stderr, "%s needs %u arguments and got %u.\n",
  849.              fD_GetName(obj), args, count+1 );
  850.         */
  851.         fF_SetError( infile, nodef ); }
  852.           count++; }
  853.         break; }
  854.  
  855.       case ',': {
  856.  
  857.         if (!obraces) {
  858.           *bnext= '\0';
  859.           DBP(( " [PROTO=%s] ", lowarg ));
  860.           fD_NewProto( obj, count, lowarg );
  861.           lowarg= bnext+1;
  862.           count++; }
  863.         break; }
  864.  
  865.       default: {
  866.         fprintf (stderr, "faulty strpbrk in line %lu.\n", infile->lineno );
  867.       }
  868.     } }
  869.       else {
  870.     /* fprintf (stderr, "faulty argument %u in line %lu.\n",
  871.         count+1, infile->lineno );
  872.      */
  873.     count=args; /* this will effectively quit the for loop */
  874.     fF_SetError( infile, nodef );
  875.       }
  876.     }
  877.     if (fD_ProtoNum(obj) != fD_RegNum(obj)) {
  878.       fF_SetError( infile, nodef );
  879.     }
  880.   }
  881.   else {
  882.     fprintf (stderr, "fD_parsepr was fooled in line %lu\n", infile->lineno );
  883.     fprintf (stderr, "function , definition %s.\n",
  884.          /* fD_GetName(obj),*/ infile->line );
  885.     fF_SetError( infile, nodef );
  886.   }
  887.  
  888.   free( buf );
  889.   return fF_GetError(infile);
  890. }
  891.  
  892.  
  893. static __inline
  894. const char * fD_GetName( const fdDef *obj )
  895. {
  896.   if (obj && obj->name) {
  897.     return obj->name; }
  898.   else {
  899.     illparams( "fD_GetName" );
  900.     return fD_nostring;
  901.   }
  902. }
  903.  
  904.  
  905. static __inline
  906. long fD_GetOffset( const fdDef *obj )
  907. {
  908.   if (obj) {
  909.     return obj->offset; }
  910.   else {
  911.     illparams( "fD_GetOffset" );
  912.     return 0;
  913.   }
  914. }
  915.  
  916.  
  917. static __inline
  918. const char * fD_GetProto (const fdDef *obj, shortcard at)
  919. {
  920.   if (obj && at>=d0 && at<illegal && obj->proto[at]) {
  921.     return obj->proto[at]; }
  922.   else {
  923.     illparams( "fD_GetProto" );
  924.     return fD_nostring;
  925.   }
  926. }
  927.  
  928.  
  929. static __inline
  930. const char * fD_GetParam( const fdDef *obj, shortcard at )
  931. {
  932.   if (obj && at>=d0 && at<illegal && obj->param[at]) {
  933.     return obj->param[at]; }
  934.   else {
  935.     illparams( "fD_GetParam" );
  936.     return fD_nostring;
  937.   }
  938. }
  939.  
  940.  
  941. static __inline
  942. regs fD_GetReg( const fdDef *obj, shortcard at )
  943. {
  944.   if (obj && at>=d0 && at<illegal) {
  945.     return obj->reg[at]; }
  946.   else {
  947.     illparams( "fD_GetReg" );
  948.     return illegal;
  949.   }
  950. }
  951.  
  952.  
  953. static __inline
  954. const char *fD_GetRegStr( const fdDef *obj, shortcard at )
  955. {
  956.   if (obj && at>=d0 && at<illegal)
  957.     return RegStr( obj->reg[at] );
  958.   else {
  959.     illparams( "fD_GetReg" );
  960.     return RegStr( illegal );
  961.   }
  962. }
  963.  
  964.  
  965. static __inline
  966. const char * fD_GetType( const fdDef *obj )
  967. {
  968.   if (obj && obj->type) {
  969.     return obj->type; }
  970.   else {
  971.     illparams( "fD_GetType" );
  972.     return fD_nostring;
  973.   }
  974. }
  975.  
  976. /* get first free param or illegal */
  977.  
  978. static __inline
  979. shortcard fD_ParamNum( const fdDef *obj )
  980. {
  981.   shortcard count;
  982.  
  983.   if (obj) {
  984.     for ( count= d0; count<illegal && fD_nostring!=obj->param[count]; count++ );
  985.     return count; }
  986.   else {
  987.     illparams( "fD_ParamNum" );
  988.     return illegal;
  989.   }
  990. }
  991.  
  992.  
  993. static __inline
  994. shortcard fD_ProtoNum( const fdDef *obj )
  995. {
  996.   shortcard count;
  997.  
  998.   if (obj) {
  999.     for ( count= d0; count<illegal && fD_nostring!=obj->proto[count]; count++ );
  1000.     return count; }
  1001.   else {
  1002.     illparams( "fD_ProtoNum" );
  1003.     return illegal;
  1004.   }
  1005. }
  1006.  
  1007. /* get first free *reg or illegal */
  1008.  
  1009. static __inline
  1010. shortcard fD_RegNum( const fdDef *obj )
  1011. {
  1012.   shortcard count;
  1013.  
  1014.   if (obj) {
  1015.     for ( count= d0; count<illegal && illegal!=obj->reg[count]; count++ );
  1016.     return count; }
  1017.   else {
  1018.     illparams( "fD_RegNum" );
  1019.     return illegal;
  1020.   }
  1021. }
  1022.  
  1023.  
  1024. int fD_cmpName (const fdDef **big, const fdDef **small)    /* for qsort */
  1025. {
  1026.   int res;
  1027.   res = strcmp (fD_GetName (*big), fD_GetName(*small));
  1028.   return res;
  1029. }
  1030.  
  1031.  
  1032. void fD_write (const fdDef * obj)
  1033. {
  1034.   shortcard count, numregs;
  1035.   char *chtmp;
  1036.   int vd;
  1037.  
  1038.   DBP(("func %s\n", fD_GetName(obj)));
  1039.  
  1040.   vd = 0;
  1041.   numregs = fD_RegNum(obj);
  1042.  
  1043.   if ((chtmp = fD_GetType(obj)) == fD_nostring) {
  1044.     fprintf (stderr, "%s has no prototype.\n", fD_GetName(obj));
  1045.     return;
  1046.   }
  1047.   if (  tolower(chtmp[0]) == 'v' &&
  1048.     tolower(chtmp[1]) == 'o' &&
  1049.     tolower(chtmp[2]) == 'i' &&
  1050.     tolower(chtmp[3]) == 'd')
  1051.     vd = 1;
  1052.  
  1053.   if (fD_ProtoNum(obj) != numregs) {
  1054.     fprintf (stderr, "%s gets %ld fd args and %ld proto%s.\n",
  1055.          fD_GetName(obj), numregs, fD_ProtoNum(obj),
  1056.          fD_ProtoNum(obj) != 1 ? "s" : "");
  1057.     return;
  1058.   }
  1059.   printf ("extern __inline %s\n%s (BASE_PAR_DECL", chtmp, fD_GetName(obj));
  1060.  
  1061.   if (numregs > 0) {
  1062.     for (count=d0; count<numregs-1; count++)
  1063.        printf (" %s %s,",fD_GetProto(obj,count),
  1064.             fD_GetParam(obj,count));
  1065.  
  1066.     printf (" %s %s",fD_GetProto(obj,count),
  1067.             fD_GetParam(obj,count));
  1068.   }
  1069.   else
  1070.     putchar('0');
  1071.  
  1072.   if (vd)
  1073.     puts (")\n{\n\tBASE_EXT_DECL");
  1074.   else
  1075.     puts (")\n{\n\tBASE_EXT_DECL\n\tregister res __asm(\"d0\");");
  1076.  
  1077.   puts ("\tregister struct Library *a6 __asm(\"a6\") = BASE_NAME;");
  1078.  
  1079.   for (count=d0; count<numregs; count++) {
  1080.     chtmp = fD_GetRegStr (obj,count);
  1081.     printf ("\tregister %s %s __asm(\"%s\") = %s;\n",
  1082.         fD_GetProto (obj,count), chtmp, chtmp, fD_GetParam (obj,count));
  1083.   }
  1084.   printf ("\t__asm __volatile (\"jsr a6@(-0x%lx)\"\n", -fD_GetOffset(obj));
  1085.  
  1086.   if (vd)
  1087.     puts ("\t: /* No Output */");
  1088.   else
  1089.     puts ("\t: \"=r\" (res)");
  1090.  
  1091.   printf ("\t: \"r\" (a6)");
  1092.  
  1093.   for (count=d0; count<numregs; count++)
  1094.     printf (", \"r\" (%s)", fD_GetRegStr(obj,count));
  1095.  
  1096.   printf ("\n\t: \"d0\", \"d1\", \"a0\", \"a1\"");
  1097.  
  1098.   for (count=d0; count<numregs; count++) {
  1099.     switch (fD_GetReg(obj,count)) {
  1100.       case d0:
  1101.       case d1:
  1102.       case a0:
  1103.       case a1: break;
  1104.       default: {
  1105.     printf (", \"%s\"", fD_GetRegStr(obj,count));
  1106.     break;
  1107.       }
  1108.     } }
  1109.  
  1110.   if (vd)
  1111.     printf (");\n}\n");
  1112.   else
  1113.     printf (");\n\treturn res;\n}\n");
  1114. }
  1115.  
  1116. #define FDS 1000
  1117.  
  1118. void main (int argc, char **argv)
  1119. {
  1120.   fdDef **mydef;
  1121.   fdDef *tmpdef= NULL,   /* a dummy to contain the name to look for */
  1122.     *founddef;     /* the fdDef for which we found a prototype */
  1123.  
  1124.   fdFile *myfile;
  1125.  
  1126.   char *tmpstr;
  1127.  
  1128.   long count, fds;
  1129.   Error lerror = false;
  1130.  
  1131.   if (argc != 3) {
  1132.     fprintf (stderr, "Usage: %s fdfilename protofilename\n", argv[0] );
  1133.     exit(20);
  1134.   }
  1135.  
  1136.   mydef = malloc (FDS*sizeof(fdDef *));
  1137.  
  1138.   if (mydef) {
  1139.  
  1140.     for (count=0; count<FDS; count++) mydef[count]= NULL;
  1141.  
  1142.     myfile = fF_ctor (argv[1]);
  1143.  
  1144.     if (myfile) {
  1145.       lerror = false;
  1146.  
  1147.       for (count= 0; count<FDS && false==lerror; count++) {
  1148.     mydef[count]= fD_ctor();
  1149.     do {
  1150.       if (false == (lerror = fF_readln (myfile))) {
  1151.         fF_SetError(myfile, false);
  1152.         lerror=fD_parsefd(mydef[count], myfile);
  1153.       }
  1154.     } while (nodef==lerror);
  1155.       }
  1156.       if (count<FDS) {
  1157.     count--;
  1158.     fD_dtor( mydef[count] );
  1159.     mydef[count]= NULL;
  1160.       }
  1161.       fds = count;
  1162.  
  1163.       /* the gnu stdlib.h seems to have a bug for qsort: int (*)(etc.) */
  1164.  
  1165.       qsort (mydef, count, sizeof(fdDef *), (void *)fD_cmpName);
  1166.  
  1167.       fF_dtor( myfile );
  1168.       myfile = fF_ctor( argv[2] );
  1169.  
  1170.       if (myfile) {
  1171.     if (!tmpdef) tmpdef= fD_ctor();
  1172.     for (lerror= false; false==lerror; ) {
  1173.       do {
  1174.         if (false==(lerror=fF_readln(myfile))) {
  1175.           fF_SetError( myfile, false );   /* continue even on errors */
  1176.           tmpstr= fF_FuncName( myfile );
  1177.           if (tmpstr) {
  1178.         fD_NewName( tmpdef, tmpstr );
  1179.         founddef= binSearch( (void **)mydef, fds, tmpdef, (void *)fD_cmpName );
  1180.         if (founddef) {
  1181.           DBP(("found (%s).\n", fD_GetName( founddef ) ));
  1182.           fF_SetError(myfile, false);
  1183.           lerror= fD_parsepr(founddef, myfile);
  1184.         }
  1185.         else fprintf (stderr, "did not find <%s> in line %lu.\n",
  1186.                   tmpstr, myfile->lineno );
  1187.         free( tmpstr );
  1188.           }
  1189.           else lerror= nodef;
  1190.         }
  1191.       } while (nodef==lerror);
  1192.     }
  1193.     fD_dtor(tmpdef);
  1194.     tmpdef= NULL;
  1195.       }
  1196.     }
  1197.     else fprintf (stderr, "Couldn't open file.\n" );
  1198.  
  1199.     strcpy (BaseNamU, BaseName);
  1200.     strupr (BaseNamU);
  1201.  
  1202.     printf (IHead,BaseNamU,BaseNamU,BaseName,BaseName);
  1203.  
  1204.     for (count=0; count<FDS && mydef[count]; count++) {
  1205.  
  1206.       /* printf("outputting %ld...\n", count); */
  1207.  
  1208.       fD_write (mydef[count]);
  1209.       fD_dtor  (mydef[count]);
  1210.       mydef[count]= NULL;
  1211.     }
  1212.  
  1213.     printf (IFoot,BaseNamU);
  1214.  
  1215.     fF_dtor( myfile );
  1216.     myfile= NULL;
  1217.  
  1218.     switch (lerror) {
  1219.       case false:      exit(0);
  1220.       case nodef:      exit(20);
  1221.       case real_error: exit(20);
  1222.       default:           exit(30);
  1223.     } }
  1224.   else {
  1225.     fprintf (stderr, "No mem for FDs\n" );
  1226.     exit(20);
  1227.   }
  1228. }
  1229.  
  1230.